GLOBAL TERRORISM ANALYSIS

Introduction

Un attentato è un atto di violenza, diretto contro un avversario chiaramente individuato, con cui si mira a eliminare il nemico o la sua rete di relazioni e interessi. L’attentato, solitamente, é il culmine di una strategia ben studiata.

Import

In [1]:
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
from datetime import datetime
from sklearn import linear_model
from sklearn.model_selection import train_test_split

Dataset study

Il dataset preso in analisi elenca tutti gli attacchi terroristici globali nell’arco degli anni 1970-2017. Contiene circa 181'000 osservazioni e 135 colonne, che però non sono state utilizzate tutte all’interno dell’analisi. Come riferimento, esso può essere reperito su Kaggle al link https://www.kaggle.com/START-UMD/gtd.

In [2]:
dfTerrorismo=pd.read_csv('csv/globalterrorismdb_0718dist.csv', low_memory=False,encoding='ISO-8859-1')

print("Dataset columns:")
print(dfTerrorismo.columns)

print("\nDataset size:",len(dfTerrorismo.index))
Dataset columns:
Index(['eventid', 'iyear', 'imonth', 'iday', 'approxdate', 'extended',
       'resolution', 'country', 'country_txt', 'region',
       ...
       'addnotes', 'scite1', 'scite2', 'scite3', 'dbsource', 'INT_LOG',
       'INT_IDEO', 'INT_MISC', 'INT_ANY', 'related'],
      dtype='object', length=135)

Dataset size: 181691

Dataset preparation

Il dataset utilizzato per le analisi contiene 18 colonne (quelle più rilevanti). Queste 18 colonne derivano da un lavoro di preparazione,in quanto il dataset originale conteneva tante colonne superflue. Si è deciso di introdurre una colonna che indicasse il numero totale di persone che hanno subito danni durante ogni attacco (morti e feriti).

In [3]:
dfTerrorismo.rename(columns={'iyear':'Anno',
                       'imonth':'Mese',
                       'iday':'Giorno',
                       'country_txt':'Nazione',
                       'region_txt':'Regione',
                       'city':'Citta',
                       'latitude':'Latitude',
                       'longitude':'Longitude',
                       'attacktype1_txt':'Tipo_attacco',
                       'target1':'Target',
                       'nkill':'Vittime',
                       'nwound':'Feriti',
                       'summary':'Riassunto',
                       'gname':'Gruppo_terroristico',
                       'targtype1_txt':'Target_type',
                       'weaptype1_txt':'Tipo_arma',
                       'motive':'Motivo'},inplace=True)
dfTerrorismo=dfTerrorismo[['Anno','Mese','Giorno','Nazione','Regione',
               'Citta','Latitude','Longitude','Tipo_attacco',
               'Vittime','Feriti','Target','Riassunto','Gruppo_terroristico',
               'Target_type','Tipo_arma','Motivo']]
dfTerrorismo["Tot_colpiti"] = dfTerrorismo["Vittime"] + dfTerrorismo["Feriti"]

GRAPHICS

The ten nations with the highest number of victims and injuries

Inziamo il documento con un grafico che mostra le 10 nazioni più colpite nel corso degli anni. Per fare ciò abbiamo sommato il numero di persone colpite per ogni nazione e lo abbiamo ordinato.

Ciò che salta all'occhio é che le zone di "guerra" sono anche quelle con il maggior numero di vittime legate agli attacchi terroristici.

In [4]:
df10PiuColpite = dfTerrorismo.groupby("Nazione").sum()
df10PiuColpite = df10PiuColpite.sort_values("Tot_colpiti",ascending=False)
df10PiuColpite = df10PiuColpite[:10]

df10PiuColpite = df10PiuColpite.sort_values("Tot_colpiti")

fig = px.histogram(df10PiuColpite,orientation="h",  y=df10PiuColpite.index,x="Tot_colpiti")
fig.layout["xaxis"]["title"] = "Number of person"
fig.layout["yaxis"]["title"] = "Nation"
fig.layout["title"] = "Iraq is the nation with the most attack"
fig.show()

Total victims and injuried per Region

In secondo primo grafico, possiamo notare la distribuzione in percentuale degli attacchi avvenuti negli anni, raggruppati per regione.

Come si può notare, la zona più colpita risulta la parte settentrionale e centrale dell’Africa,seguito dal sud asiatico. Ciò potrebbe essere dovuto alla maggior presenza di gruppi terroristici locali e a un forte attaccamento alla religione islamica. In opposto, la zona meno colpita risulta essere l’Oceania e l'Australia; in tale zone è stato raro nel corso degli anni lo svolgimento di attacchi terroristici.

Per quanto anche l’Europa negli anni non sembra essere stata presa “troppo” sotto assedio negli anni, a parte gli ultimi in cui si sono verificati diversi attacchi da parte dI alcuni militanti affiliati all’ ISIS.

Questi dati sono relativi al numero di attacchi avvenuti nei 47 anni rappresentati dal dataset, e non alla popolazione della regione mostrata.

In [5]:
dfVictimsAndInjuried= dfTerrorismo.groupby('Regione').sum()
dfVictimsAndInjuried["Totale"] = dfVictimsAndInjuried["Vittime"] + dfVictimsAndInjuried["Feriti"]
dfVictimsAndInjuried = dfVictimsAndInjuried.sort_values("Totale",ascending=False)

total = dfVictimsAndInjuried["Totale"].sum()

dfVictimsAndInjuried["Percentage_Victims_Injuried"] = (dfVictimsAndInjuried["Totale"]/total) * 100

fig = px.bar(dfVictimsAndInjuried,orientation="h",x='Percentage_Victims_Injuried',barmode="stack")
fig.update_layout(showlegend=False)
fig.layout["title"] = "In Norther Asia there was more victimis and injuries due to terrostic attack between 1970 and 2017"
fig.layout["yaxis"]["title"] = "Region"
fig.layout["xaxis"]["title"] = "Percentage Victims And Injuries"
fig.show()

Number of victim by terrorist group

Continuiamo ora con un grafico che rappresenta la distribuzione delle vittime per gruppo terroristico.

La maggioranza delle vittime è stata causata da gruppi terroristici, la cui denominazione è sconosciuta. Questo dato é dovuto al fatto che molti dati sono riconducibili ad attacchi effettuati da gruppi terrosistici locali e poco conosciuti in america, da dove proviene il grafico.

In [6]:
dfGroups = dfTerrorismo.groupby("Gruppo_terroristico").sum()
dfGroups = dfGroups.sort_values("Vittime",ascending=False)
dfGroups = dfGroups[:15]
fig = px.bar(dfGroups,y=dfGroups.index,x="Vittime",orientation="h")
fig.layout["xaxis"]["title"] = "Victims"
fig.layout["yaxis"]["title"] = "Terrorist Groups"
fig.layout["title"] = "The most attack are from unknow group"
fig.show()

Ratio of victim / number of attacks for each type of attack

In questo grafico ciò che si voleva mostare é quale tipo di attacco é il più disastroso.

Possiamo notare che il ratio tra il numero di attacchi e vittime é maggiore per il tipo di attacchi "dirottamento". Questo può essere dovuto al fatto che in questo tipo di attacchi rientra anche l'attacco alle torri gemelle che, é stato l'attacco con più vittime in assoluto. Un'altro dei possibili motivi può essere riconducibile al fatto che, un attacco di tipo dirottamento, non viene scelto spesso e, perciò, il ratio clacolato di questo tipo di attacchi aumenta

In [7]:
dfTerrorismoTypeAttack = dfTerrorismo.groupby("Tipo_attacco").sum()
dfTerrorismoTypeAttack["Tot_attack"] = dfTerrorismo.groupby("Tipo_attacco").count()["Anno"]
dfTerrorismoTypeAttack["percent_attack"] = dfTerrorismoTypeAttack["Tot_colpiti"] / dfTerrorismoTypeAttack["Tot_attack"]

dfTerrorismoTypeAttack = dfTerrorismoTypeAttack.sort_values("percent_attack",ascending=True)

fig = px.histogram(dfTerrorismoTypeAttack,orientation="h",  y=dfTerrorismoTypeAttack.index,x="percent_attack",
                    hover_data=["Tot_colpiti","Tot_attack"])
fig.layout["xaxis"]["title"] = "Victim / Num attack"
fig.layout["yaxis"]["title"] = "Type attack"
fig.layout["title"] = "The bombing attack is the most used but have a low ratio victims / number of attack"
fig.show()

dfDataGraphic = dfTerrorismoTypeAttack.drop(columns=
                    dfTerrorismoTypeAttack.columns.difference(['Tot_colpiti','Tot_attack','percent_attack']))
dfDataGraphic = dfDataGraphic.sort_values("percent_attack",ascending=False)
dfDataGraphic
Out[7]:
Tot_colpiti Tot_attack percent_attack
Tipo_attacco
Hijacking 20642.0 659 31.323217
Unarmed Assault 14791.0 1015 14.572414
Hostage Taking (Barricade Incident) 7465.0 991 7.532795
Bombing/Explosion 514233.0 88255 5.826673
Unknown 39606.0 7276 5.443375
Armed Assault 212386.0 42669 4.977525
Assassination 37209.0 19312 1.926729
Hostage Taking (Kidnapping) 20267.0 11158 1.816365
Facility/Infrastructure Attack 6293.0 10356 0.607667

Trend attack

In questo terzo grafico, vediamo la distribuzione del "trend" degli attacchi terroristici per anno.

A partire dal 2011 vi è stato un notevole incremento degli attacchi, sicuramente per l’aumento dell’attività dei gruppi terroristici locali e quindi sconosciuti.

In opposto gli anni con con meno attacchi risalgono all’inizio degli anni ‘70, probabilmente all’alba dell’inizio della formazione di gruppi terroristici.

In [8]:
dfAnno = dfTerrorismo["Anno"].value_counts(ascending=False)
years = dfAnno.index.sort_values(ascending=True)
dfAnno = dfAnno.sort_values(ignore_index =True)

fig = px.line(x=years,y=dfAnno.values)
fig.layout["title"] = "Attacks have increased since 2011"
fig.layout["xaxis"]["title"] = "Year"
fig.layout["yaxis"]["title"] = "Total attacks per year"
fig.update_layout(showlegend=False)
fig.show()

Plot of the europe durng the years

In questo grafico ciò che abbiamo rappresentato su una mappa geografica i tipi di attacchi durante i 47 anni rappresentati dal dataset. La prima cosa che si nota é che c’è una distribuzione abbastanza omogenea in tutta europa degli attacchi di tipo “attacco alle strutture”.

Essendoci molti dati, é difficile estrarre informazioni precise, per questo motivo abbiamo creato lo stesso grafico con uno slider con cui è possibile selezionare l’anno. In questo modo oltre al tipo di attacco possiamo notare dei “trend” di tipo di attacco e della zona che negli anni cambiano.

Un esempio lampante si può notare in italia che, intorno alla fine degli anni ‘70 è stata vittima di molti attacchi.

In [9]:
worldPlot = px.scatter_mapbox(dfTerrorismo, lat="Latitude", lon="Longitude",zoom=3,
                             hover_name="Citta", hover_data=["Gruppo_terroristico","Anno"], labels={"Tipo_attacco": "Type attack"},
                              color="Tipo_attacco",opacity=0.3,center={'lon':8,'lat':48})
worldPlot.update_layout(mapbox_style="open-street-map")
worldPlot.update_layout(title="There is a relation between position and the type of attack")
worldPlot.show()
worldPlot.write_html("europePlot.html")
In [10]:
worldPlot = px.scatter_mapbox(dfTerrorismo, lat="Latitude", lon="Longitude",zoom=3,
                             hover_name="Citta", hover_data=["Gruppo_terroristico"], labels={"Tipo_attacco": "Type attack"},
                              color="Tipo_attacco",animation_frame="Anno",center={'lon':8,'lat':48})
worldPlot.update_layout(mapbox_style="open-street-map")
worldPlot.update_layout(title="During the years the type of attack and the position changes")
worldPlot.show()
worldPlot.write_html("europePlotByYear.html")

Plot of the world attack

Come per l'europa abbiamo deciso di avere un garfico mondiale di tutti gli attacchi che ci sono stati nel mondo tra il 1970 e il 2017. Per mostrare meglio l'impatto dei diversi attacchi nel mondo, oltre a colorare per tipo di attacco, ciò che abbiamo deciso di fare é di mostare con un punto più grande gli attacchi più gravi.

Confrontando l'Europa con il resto del mondo possiamo notare che la situazione è molto più controllata in quanto i "puntini" sono quasi invisibili (tranne per alcuni attacchi come quello a nizza del 2016).

Un'altra osservazione che si può fare é che, come ci si può aspettare, nelle zone di guerra ci sono molti attacchi gravi.

In [11]:
dfWorld = dfTerrorismo.dropna()
worldPlot = px.scatter_mapbox(dfWorld, lat="Latitude", lon="Longitude",zoom=0,
                             hover_name="Citta", hover_data=["Gruppo_terroristico","Anno"],
                              color="Tipo_attacco",size="Tot_colpiti",labels={"Tipo_attacco": "Type attack"})
worldPlot.update_layout(mapbox_style="open-street-map")
worldPlot.update_layout(title="There is a relation between position and the gravity of an attack")

worldPlot.show()
worldPlot.write_html("worldPlot.html")

Relation between attck and type attack

Questo grafico vuole mostrare il rapporto tra vittime, feriti e il tipo di attacco. Come si nota, soprattutto da per gli attacchi di tipo “bombardamento” e “sequestro di ostaggi” si può vedere che sono rispettivamente i tipi di attacchi con più e meno vittime.

Il punto più esterno, quindi quello con più vittime in assoluto, si vede ad occhio ed é l’attacco alle torri gemelle nel 2001. Come per il punto precedente ci sono molte informazioni nello stesso grafico quindi, per alleggerirlo è stato aggiunto uno slider con l’anno.

Facendo scorrere lo slider si vede che nella prima metà degli anni 70 gli attacchi sono molto meno rispetto a quelli degli anni successivi e che, a partire degli anni 2000 gli attacchi di tipo “assalto armato” lasciano spazio a quelli di tipo “bombardamento”.

In [12]:
fig = px.scatter(dfTerrorismo,x="Feriti",y="Vittime",color="Tipo_attacco",hover_data=["Gruppo_terroristico","Citta","Anno"],
                opacity=0.2,labels={"Tipo_attacco": "Type attack"})

fig.update_layout(title = "There is a relation between numer of death/injured and type of attack ")
fig.layout["xaxis"]["title"] = "injuried"
fig.layout["yaxis"]["title"] = "Victim"

fig.update_xaxes(type="log")
fig.update_yaxes(type="log")
fig.show()
fig.write_html("attackDeathRelation.html")
In [13]:
fig = px.scatter(dfTerrorismo,x="Feriti",y="Vittime",color="Tipo_attacco",hover_data=["Gruppo_terroristico","Citta"],
                 animation_frame="Anno",opacity=0.3,labels={"Tipo_attacco": "Type attack"})

fig.update_layout(title = "There is a relation between type of attack and the year")
fig.layout["xaxis"]["title"] = "injuried"
fig.layout["yaxis"]["title"] = "Victim"

fig.update_xaxes(type="log")
fig.update_yaxes(type="log")
fig.show()
fig.write_html("attackDeathRelationYearAnimation.html")

Linear regression

Concludiamo il nostro progetto con una regressione lineare tra il numero di vittime e il numero di feriti.

Ciò che ci si aspetta è una crescita proporzionale, in quanto “tipicamente” un numero di feriti maggiore implica un numero di morti maggiore.

Questa relazione, come dimostrerà il coefficiente di correlazione, esiste ed è rappresentata dal coefficiente angolare. Infatti,R^2, ci conferma la “bontà” della correlazione che vale circa 0.49 nel caso del training e 0.75 nel dataset di test. Inoltre, un coefficiente angolare di 0.163 implica che per ogni ferito, solitamente, non si hanno vittime, rendendo questa tendenza piuttosto ottimale.

In [14]:
#Preparation of linear regression
[dfTrain,dfTest] = train_test_split(dfTerrorismo, test_size=0.3, random_state=42)

dfTrain = dfTrain.dropna()
dfTest = dfTest.dropna()

xTrain = dfTrain['Feriti'].values
yTrain = dfTrain['Vittime'].values

xTest = dfTest['Feriti'].values
yTest = dfTest['Vittime'].values

xTrain = np.reshape(xTrain,(-1,1))
xTest = np.reshape(xTest,(-1,1))

reg = linear_model.LinearRegression()
reg.fit(xTrain,yTrain)
Out[14]:
LinearRegression()

Linerar regression between injuries and deaths

In [15]:
fig = go.Figure(go.Scatter(x=xTrain.flatten(),y=yTrain,mode="markers",name="residual"))
fig.add_trace(go.Scatter(x=xTest.flatten(),y=reg.predict(xTest),mode="lines",name="estimate"))

fig.update_layout(title = "Relation between Injuries and Deaths")
fig.update_xaxes(title="Injured")
fig.update_yaxes(title="Death")

fig.add_trace(go.Scatter())

Regression parameter

In [16]:
R_2_train = reg.score(xTrain,yTrain)
R_2_test = reg.score(xTest,yTest)
print(f"R^2 train: {R_2_train}")
print(f"R^2 test: {R_2_test}")
print(f"Coefficiente angolare:{reg.coef_}")
print(f"Intercetta: {reg.intercept_}")
R^2 train: 0.49269201425940057
R^2 test: 0.7483786142818681
Coefficiente angolare:[0.16320907]
Intercetta: 1.6017042254991978